require "config/callcache_parser_config.rb"
require "app/helpers/callcache_parser_helper.rb"
require "date"
require "json"
require "config/areacode.rb"
require "config/country_number.rb"


class CallcacheParserController < ApplicationController
  helper :callcache_parser
 
  #####################################################
  ##
  ## functions for the parsing
  ##
  #####################################################
  
  @array_raw_data = nil
  @provider    = nil
  @ccode_dest  = nil
  @ccode_src   = nil
    
  def start
    #TODO: implement access code
    @access_code = params[:access_code] 
    if params[:nuclear_bomb] == "fire"
      rollback_file_names(FILEROOT) #TODO: STOP CRONTAB before you use this !!!!!!
      ##testing purpose, remove # if you want to remove '.imported' extension for the debugging purpose. Be careful that the script does not check the duplicate record!!  
    end     
    parsing_main()   
    test() 
  end
  
  def parsing_main
    iterate_folders(FILEROOT) # recursive function
  end
  
  def process_file(filepath_name)
    category = "processFile"
    # prepare
    log(category, "************************************starting %s ***************************" % filepath_name)
    start   = DateTime.now
    @array_raw_data, @provider = get_raw_data(filepath_name)
    one = DateTime.now
    h,m,s,frac = Date.day_fraction_to_time(one-start)
    log(category, "time for get_raw_data: %dm %ds" % [m, s])
    
    status_token = true
    # STEP 1 callcache_raw            ##############################################################
    #if status_token == true
      status_token = callcache_raw()
      two   = DateTime.now
      h,m,s,frac = Date.day_fraction_to_time(two-one)
      log(category, "time for callcache_raw: %dm %ds" % [m, s])
    #end
  
    # STEP 2 fact_dest_trunk_group    ##############################################################
    #if status_token == true
      status_token = fact_dest_trunk_group(@array_raw_data)
      three = DateTime.now
      h,m,s,frac = Date.day_fraction_to_time(three-two)    
      log(category, "time for fact_dest_trunk_group: %dm %ds" % [m, s])
    #end
    
    # STEP 3 fact_src_phone_number    ##############################################################
    #if status_token == true
      status_token = fact_src_phone_number(@array_raw_data)
      four  = DateTime.now
      h,m,s,frac = Date.day_fraction_to_time(four-three)
      log(category, "time for fact_src_phone_number: %dm %ds" % [m, s])
    #end
    # STEP 4 fact_count_by_dest_ip    ##############################################################
    #if status_token == true
      status_token = fact_count_by_dest_ip(@array_raw_data)
      five  = DateTime.now
      h,m,s,frac = Date.day_fraction_to_time(five-four)
      log(category, "time for fact_count_by_dest: %dm %ds" % [m, s])
    #end
    # STEP 5 fact_count_by_src_ip     ############################################################## 
    #if status_token == true  
      status_token = fact_count_by_src_ip(@array_raw_data)
      e     = DateTime.now
      h,m,s,frac = Date.day_fraction_to_time(e-five)    
      log(category, "time for fact_count_by_src_ip: %dm %ds" % [m ,s])
    #end
    
    #if status_token == true
      h,m,s,frac = Date.day_fraction_to_time(e-start)
      log(category, "*********total time for processing one file: %dm %ds" % [m, s])
    #end
  end 
    
  ###############################################################################################
  ##
  ## This function returns the array of callcache raw data from a given file path 
  ## TODO: eliminate duplicated record in the array
  ##
  ###############################################################################################
  def get_raw_data(filepath)

    array_of_array = Array.new
    puts filepath
    '''
    Do we need to change the extfile? Currently yes.
    ** At the end of the function, we change the extfile to mark that it is imported.
    '''
    if File.extname(filepath) != ".callcache" # This checking is for the case that the scripts that generate callcache directly calls this script
      return nil
    end

    infile = File.new(filepath, "r")

    stringArray = ["","","","",""]

    '''
    #src_carrier, src_ip, src_phone, --->, dest_carrier, dest_ip, dest_phone, duration
    Sample
    peerless-stlouis/0 ip:208.93.45.134 ani:+16619491852 ---> g2mvcb7-sip1.iad/0 ip:10.21.70.20 dnis:19143390012 dur:6918s
    '''

    filebasename          = File.basename(filepath, ".callcache")
    sbcid_and_timestamp   = filebasename.split('-')

    infile.each {|line|

      if line =~ /Call /
        dataArray1 = {}
        dataArray2 = {}

        dataArray1[ID] = sbcid_and_timestamp[0] + sbcid_and_timestamp[1] + line
        dataArray2[ID] = dataArray1[ID]

        stringArray[0] = infile.readline # to get the offset of the second line, there must be a better way to do this
        stringArray[1] = infile.readline
        stringArray[2] = infile.readline
        stringArray[3] = infile.readline
        stringArray[4] = infile.readline

        temp1       = stringArray[1].gsub("Neutral Tandem/0 ip:","Neutral_Tandem/0 ip:").split
        temp2       = stringArray[3].gsub("Neutral Tandem/0 ip:","Neutral_Tandem/0 ip:").split

        dataArray1  = {ID => sbcid_and_timestamp[0] + sbcid_and_timestamp[1] + line,
          SBC_ID => sbcid_and_timestamp[0], TIMESTAMP => sbcid_and_timestamp[1],
          SRC_CARRIER => temp1[0],          SRC_IP => temp1[1],   SRC_PHONE => temp1[2],
          DEST_CARRIER => temp1[4],         DEST_IP => temp1[5],  DEST_PHONE => temp1[6],
          DURATION => temp1[7],             CREATED_AT => Time.new.strftime("%Y-%m-%d %H:%M:%S")
        }

        dataArray2  = {ID => sbcid_and_timestamp[0] + sbcid_and_timestamp[1] + line,
          SBC_ID => sbcid_and_timestamp[0], TIMESTAMP => sbcid_and_timestamp[1],
          SRC_CARRIER => temp2[0],          SRC_IP => temp2[1],   SRC_PHONE => temp2[2],
          DEST_CARRIER => temp2[4],         DEST_IP => temp2[5],  DEST_PHONE => temp2[6],
          DURATION => temp2[7],             CREATED_AT => Time.new.strftime("%Y-%m-%d %H:%M:%S")
        }
        
        #########################################################################################
        ##
        ## strip
        ##
        #########################################################################################

        dataArray1  = myStrip(dataArray1)
        dataArray2  = myStrip(dataArray2)
        
        #########################################################################################
        ##
        ## update the "SRC country code" 
        ## for the "DEST country code", please take a look at the bottom. it is because of phid
        ##
        #########################################################################################
        dataArray1[SRC_CCODE] = get_iso_country_code_src(dataArray1[SRC_PHONE])
        
        #########################################################################################
        ##
        ## check the pairs if they match together or not
        ##
        #########################################################################################

        if checkPair(dataArray1, dataArray2)
          array_of_array << dataArray1
        else
          puts "Fail: The pair are not the same in " + dataArray1[ID]
          log("W","In %s, pairs are not the same" % dataArray1[ID])
        end # if checkPair
      end # if line =~ /Call /

    }

    infile.close
    File.rename(filepath, filepath + NEWEXT)
    
    #########################################################################################
    ##
    ## check duplicate ids and remove from return value
    ## TODO: speed up this part if time allows, 
    ## Currently, the logic is (SBC_ID and Timestamp + Row number)
    ##
    #########################################################################################
    return_array = Array.new
    cond = "id='%s' " % array_of_array[0][ID] if array_of_array.size > 0
    count = 0
    step  = 900
        
    while count < array_of_array.size
      start = count
      endding = count + step if (start + step) < array_of_array.size
      endding = array_of_array.size if (start+step) >= array_of_array.size
      
      #puts "start: #{start}"
      #puts "endding: #{endding}" 
      for i in start...endding        
        cond += "or id='%s' " % array_of_array[i][ID]
        count+=1
      end

=begin TODO:temporarily
      @data1 = array_of_array.size
      @dup_data = CallcacheRaw.find(:all, :select=>"id", :conditions=>cond) #id=? or
      temp_array = Array.new
      for t in @dup_data
        temp_array << t["id"]
      end
=end       
      for hash in array_of_array
        return_array << hash # TODO: temporarily removed if !temp_array.include? hash[ID].to_s I am not checking duplicate !!
      end
      @data2 = return_array.size # for debugging
      
      
    end
    
    
    
    
    
    ##################################################
    ##
    # Setup the Phid Cache
    ##
    ##################################################
    dest_numbers = Array.new
    for hash in return_array
      dest_numbers << hash[DEST_PHONE]      
    end
    
    provider = find_group_provider_name_plural(dest_numbers)
    ccode_dest = get_iso_country_code_dest_plural(dest_numbers)
    
    
    #########################################################################################
    ##
    ## update the "DEST country code" 
    ## for the "DEST country code", please take a look at the bottom. it is because of phid
    ##
    #########################################################################################
    if return_array != nil
      for item in return_array
        if item[DEST_PHONE] != nil
          key = item[DEST_PHONE].gsub("+","")
          if ccode_dest.has_key?(key)
            item[DEST_CCODE] = ccode_dest[key][0] 
          end          
        end        
      end  
    end
    
   status = true
    return return_array, provider, status
  end # end of the function
    
  ####################################################
  ##               MAIN FUNCTIONS  
  ####################################################
  ##
  ## Group 1. function for the archive table
  ##
  ####################################################
  # 1. for the archive table 
  def callcache_raw()
    if @array_raw_data == nil
      puts "**** callcache_raw(): Nothing is inserted."
      return false
    end
    
    for raw_data in @array_raw_data
      c = CallcacheRaw.new
      c.identifier    = raw_data[ID]
      c.SBCID         = raw_data[SBC_ID]
      c.timestamp     = raw_data[TIMESTAMP]
      c.src_carrier   = raw_data[SRC_CARRIER]
      c.src_ip        = raw_data[SRC_IP]
      c.src_phone     = raw_data[SRC_PHONE]
      c.dest_carrier  = raw_data[DEST_CARRIER]
      c.dest_ip       = raw_data[DEST_IP]
      c.dest_phone    = raw_data[DEST_PHONE]
      c.duration      = raw_data[DURATION]
      c.src_ccode     = raw_data[SRC_CCODE]
      c.dest_ccode    = raw_data[DEST_CCODE]
      
      c.save!
    end

    log("callcache_raw", "**** callcache_raw(): %s record inserted." % @array_raw_data.size)
  end

  #####################################################
  ##
  ## Group 2. functions for the fact tables
  ##
  #####################################################
  # 2. per destination trunk group
  def fact_dest_trunk_group(array_raw_data)
    return false if array_raw_data == nil
    
    
    ###################################################
    ## TODO It is not fully optimized. We can save number of db accessing. 
    ###################################################
    for data in array_raw_data
      phone_number = data[DEST_PHONE]
      vcb_name     = data[DEST_CARRIER]
      vcb_ip       = data[DEST_IP]
      vcb_data_center = data[SBC_ID].split(".")[1]
      timestamp    = data[TIMESTAMP]
      iso_country_code = data[DEST_CCODE]
      
      src_carrier               = data[SRC_CARRIER]
      src_ip                    = data[SRC_IP]
      dest_vcb                  = find_dest_vcb(vcb_name, vcb_ip, vcb_data_center) #TODO: changed by ansh
      trunk_group_col_name      = find_trunk_group_col_name(phone_number)
      trunk_group_provider_name = find_group_provider_name(phone_number, @provider)[0]
      identifying_phone_number  = get_identifying_phone_number(phone_number, data[DEST_CCODE])
      mask                      = get_mask(data[DEST_CCODE])
      
      trunk_group_carrier       = find_trunk_group_carrier(src_carrier, src_ip, dest_vcb, trunk_group_col_name, trunk_group_provider_name, identifying_phone_number, mask, iso_country_code)
                  
      instance        = FactDestTrunkGroup.find_or_initialize_by_dimen_trunk_group_carrier_id_and_timestamp(trunk_group_carrier.id, timestamp)
      instance.calls  = 0 if instance.calls == nil
      instance.calls += 1
      instance.save!
    end
    
    return true
  end

  # 3. per source phone number
  def fact_src_phone_number(array_raw_data)
    return false if array_raw_data == nil
    
    for r in array_raw_data
      src_phone    = r[SRC_PHONE]
      src_carrier  = r[SRC_CARRIER]
      src_ip       = r[SRC_IP]
      iso_country_code = r[SRC_CCODE]
      
      src_location = find_src_location(src_phone, src_carrier, src_ip, iso_country_code)
      timestamp    = r[TIMESTAMP]
      
      instance = FactSrcPhoneNumber.find_or_initialize_by_timestamp_and_dimen_src_location_id(timestamp, src_location.id)
      instance.calls = 0 if instance.calls == nil
      instance.calls += 1
      instance.save!
    end
    
    return true
  end

  # 4. per destination ip
  def fact_count_by_dest_ip(array_raw_data)
    return false if array_raw_data == nil
    
    for r in array_raw_data      
       instance = FactCountByDestIp.find_or_initialize_by_timestamp_and_dest_ip(r[TIMESTAMP], r[DEST_IP])
       instance.calls = 0 if instance.calls == nil       
       instance.calls += 1
       instance.save!
    end
   
   return true
  end

  #5. per source ip
  def fact_count_by_src_ip(array_raw_data)
    return if array_raw_data == nil
    
    for r in array_raw_data
      instance = FactCountBySrcIp.find_or_initialize_by_timestamp_and_src_ip(r[TIMESTAMP], r[SRC_IP])
      instance.calls = 0 if instance.calls == nil
      instance.calls += 1
      instance.save!
    end
    
    return true
  end
   

  ####################################################
  ##
  ## fucntions for Test Driven Development
  ##
  ####################################################
    
  def tdd
    fail = 0
    @tdd_output = ""
    
    @tdd_output += "********************************************************************************<br />"
    @tdd_output += "********************************************************************************<br />"
    @tdd_output += "** This is unit_test function. Please take a look at cdr_parser_controller.rb **<br />"
    @tdd_output += "********************************************************************************<br />"
    @tdd_output += "********************************************************************************<br />" 
    @tdd_output += "<br />"
    
    fail += unit_test('get_iso_country_code("1222333")      - dest'         , get_iso_country_code_dest("1222333")[0]             , "UNKNOWN")
    fail += unit_test('get_iso_country_code("19178812475")  - dest'         , get_iso_country_code_dest("19178812475")[0]         , "US")
    fail += unit_test('get_iso_country_code("12223334444")  - dest'         , get_iso_country_code_dest("12223334444")[0]         , "UNKNOWN")
    fail += unit_test('get_iso_country_code("7123387124")   - dest'         , get_iso_country_code_dest("7123387124")[0]       , "US")
    fail += unit_test('get_iso_country_code("17123387124")  - dest'        , get_iso_country_code_dest("17123387124")[0]       , "US")
    fail += unit_test('get_iso_country_code("9143390026")   - dest'         , get_iso_country_code_dest("9143390026")[0]       , "US")
    fail += unit_test('get_iso_country_code("19143390026")  - dest'        , get_iso_country_code_dest("19143390026")[0]       , "US")
    fail += unit_test('get_iso_country_code("317508912557") - dest'         , get_iso_country_code_dest("317508912557")[0]       , "UNKNOWN")
    fail += unit_test('get_iso_country_code("43720880312")  - dest'         , get_iso_country_code_dest("43720880312")[0]         , "AT")
    fail += unit_test('get_iso_country_code("41615000475")  - dest'         , get_iso_country_code_dest("41615000475")[0]         , "CH")
    @tdd_output += "<br />"
    
    fail += unit_test('get_iso_country_code("1222333")      - src'         , get_iso_country_code_src("1222333")[0]             , "UNKNOWN")
    fail += unit_test('get_iso_country_code("19178812475")  - src'         , get_iso_country_code_src("19178812475")[0]         , "UNKNOWN")
    fail += unit_test('get_iso_country_code("12223334444")  - src'         , get_iso_country_code_src("12223334444")[0]         , "UNKNOWN")
    fail += unit_test('get_iso_country_code("7123387124")   - src'         , get_iso_country_code_src("7123387124")[0]       , "US")
    fail += unit_test('get_iso_country_code("17123387124")   - src'        , get_iso_country_code_src("17123387124")[0]       , "US")
    fail += unit_test('get_iso_country_code("9143390026")   - src'         , get_iso_country_code_src("9143390026")[0]       , "US")
    fail += unit_test('get_iso_country_code("19143390026")   - src'        , get_iso_country_code_src("19143390026")[0]       , "US")
    fail += unit_test('get_iso_country_code("317508912557") - src'         , get_iso_country_code_src("317508912557")[0]       , "UNKNOWN")
    fail += unit_test('get_iso_country_code("43720880312")  - src'         , get_iso_country_code_src("43720880312")[0]         , "AT")
    fail += unit_test('get_iso_country_code("41615000475")  - src'         , get_iso_country_code_src("41615000475")[0]         , "CH")
    @tdd_output += "<br />"

    fail += unit_test('get_mask("US")'  , get_mask("US")  ,   "0111111")
    fail += unit_test('get_mask("XX")'  , get_mask("XX")  ,   "11")
    fail += unit_test('get_mask("NYI")' , get_mask("NYI") ,   "11")
    fail += unit_test('get_mask("XX")'  , get_mask("SZ")  ,   "111")
    fail += unit_test('get_mask("NYI")' , get_mask("KR") ,    "1111")
    @tdd_output += "<br />"
    
    fail += unit_test('get_mask("US")'                              , get_mask("US")                              , "0111111")
    fail += unit_test('get_mask("XX")'                              , get_mask("XX")                              , "11")
    @tdd_output += "<br />"
        
    fail += unit_test('get_identifying_phone_number("12223334444", false)' , get_identifying_phone_number("12223334444", false) , "12223334444")
    fail += unit_test('get_identifying_phone_number("1222333", false)'     , get_identifying_phone_number("1222333", false)     , "1222333")
    fail += unit_test('get_identifying_phone_number("4", false)'           , get_identifying_phone_number("4", false)           , "4")    
    fail += unit_test('get_identifying_phone_number(nil, false)'           , get_identifying_phone_number(nil, false)           , "")
    fail += unit_test('get_identifying_phone_number("7123387124", false)'        , get_identifying_phone_number("7123387124", false)  , "712338")
    fail += unit_test('get_identifying_phone_number("17123387124", false)'        , get_identifying_phone_number("17123387124", false)  , "712338")
    fail += unit_test('get_identifying_phone_number("317508912557", false)'      , get_identifying_phone_number("317508912557", false), "317508912557")
    fail += unit_test('get_identifying_phone_number("43720880312", false)'       , get_identifying_phone_number("43720880312", false) , "43")    
    fail += unit_test('get_identifying_phone_number("41615000475", false)'       , get_identifying_phone_number("41615000475", false) , "41")
    @tdd_output += "<br />"
    
    fail += unit_test('get_country_number("US")'      , get_country_number("US"), "1")
    fail += unit_test('get_country_number("SZ")'      , get_country_number("SZ"), "268")
    fail += unit_test('get_country_number("KR")'      , get_country_number("KR"), "82")    
    fail += unit_test('get_country_number("MS")'      , get_country_number("MS"), "1664")
    fail += unit_test('get_country_number("XX")'      , get_country_number("XX"), nil)
    @tdd_output += "<br />"
    
    fail += unit_test('get_city_state("7123387124")', get_city_state("7123387124",    "US")[1], "")
    fail += unit_test('get_city_state("9143390026")', get_city_state("9143390026",    "US")[1], "")
    fail += unit_test('get_city_state("19178812475")', get_city_state("19178812475",  "US")[1], "")
    @tdd_output += "<br />"
    
    #fail += unit_test('get_src_location("phone_number")', find_src_location("phone_number","src_carrier", "src_ip","US"), "")
    #fail += unit_test('get_src_location("phone_number")', find_src_location("phone_number","src_carrier", "src_ip","US"), "")
    #fail += unit_test('get_src_location("phone_number")', find_src_location("phone_number","src_carrier", "src_ip","US"), "")
    @tdd_output += "<br />"
    
    fail += unit_test('find_dest_vcb(vcb_name, vcb_ip)', find_dest_vcb("vcb_name", "vcb_ip"), "")
    fail += unit_test('find_dest_vcb(vcb_name, vcb_ip)', find_dest_vcb("vcb_name", "vcb_ip"), "")
    fail += unit_test('find_dest_vcb(vcb_name, vcb_ip)', find_dest_vcb("vcb_name", "vcb_ip"), "")
    @tdd_output += "<br />"
    
    fail += unit_test('find_trunk_group_col_name(phone_number)', find_trunk_group_col_name("phone_number"), "")
    fail += unit_test('find_trunk_group_col_name(phone_number)', find_trunk_group_col_name("phone_number"), "")
    fail += unit_test('find_trunk_group_col_name(phone_number)', find_trunk_group_col_name("phone_number"), "")
    @tdd_output += "<br />"
    
    fail += unit_test('find_group_provider_name("7123387124")', find_group_provider_name("7123387124", nil)[0], "GLCC")
    fail += unit_test('find_group_provider_name("19178812475")', find_group_provider_name("19178812475", nil)[0], "UNKNOWN")
    fail += unit_test('find_group_provider_name(phone_number)', find_group_provider_name("phone_number", nil)[0], "")
    @tdd_output += "<br />"
    
    fail += unit_test('find_group_provider_name_plural(["7123387124","19178812475"])' , find_group_provider_name_plural(["7123387124","19178812475"]), "GLCC")
    fail += unit_test('find_group_provider_name_plural(["19178812475","7123387124"])' , find_group_provider_name_plural(["19178812475","7123387124"]), "UNKNOWN")
    fail += unit_test('find_group_provider_name_plural(phone_number)'                 , find_group_provider_name_plural(["phone_number"]), "")
    @tdd_output += "<br />"
    
    fail += unit_test('get_iso_country_code_plural("9143390026","19143390026","43720880312","41615000475")   - dest'          , get_iso_country_code_dest_plural(["9143390026","19143390026","43720880312","41615000475"])      , "US")
    fail += unit_test('get_iso_country_code_plural("19143390026")  - dest'                                                    , get_iso_country_code_dest_plural(["19143390026"])       , "US")
    fail += unit_test('get_iso_country_code_plural("317508912557") - dest'                                                    , get_iso_country_code_dest_plural(["317508912557"])       , "UNKNOWN")
    fail += unit_test('get_iso_country_code_plural("43720880312","41615000475")  - dest'                                      , get_iso_country_code_dest_plural(["43720880312","41615000475"])       , "AT")
    fail += unit_test('get_iso_country_code_plural("41615000475")  - dest'                                                    , get_iso_country_code_dest_plural(["41615000475"])       , "CH")
    @tdd_output += "<br />"
    
    @tdd_output += "<br />"
    @tdd_output += "<br />"
    
    @tdd_output += "<br />"
    @tdd_output += "<br />"
    
    #fail += unit_test('', , "")
    #fail += unit_test('', , "")
    #fail += unit_test('', , "")
    
    @tdd_output += "We have %s failure(s).<br />" % fail
    
    #l = find_src_location("12223334444", "src_provider", "src_ip")
    #@tdd_output += "<br />"
    #@tdd_output += "src_location for 12223334444: id: %d, id phone %s, iso: %s, city: %s, mask: %s" % \
    #[l.id, l.identifying_phone_number, l.iso_country_code, l.city, l.mask]

  end
  
  def tdd2
    fail = 0
    @tdd_output2 =""
    @tdd_output2 += "********************************************************************************<br />"
    @tdd_output2 += "********************************************************************************<br />"
    @tdd_output2 += "** This is unit_test function. Please take a look at cdr_parser_controller.rb **<br />"
    @tdd_output2 += "********************************************************************************<br />"
    @tdd_output2 += "********************************************************************************<br />" 
    @tdd_output2 += "<br />"
    
    fail += unit_test2('get_iso_country_code("+1949")          - src'         , get_iso_country_code_src("+1949")             , "UNKNOWN")
    fail += unit_test2('get_iso_country_code("+19167472981")   - src'         , get_iso_country_code_src("+19167472981")      , "US")
    fail += unit_test2('get_iso_country_code("+19992539056")   - src'         , get_iso_country_code_src("+19992539056")      , "US")
    fail += unit_test2('get_iso_country_code("+6598320921")    - src'         , get_iso_country_code_src("+6598320921")       , "SG")
    fail += unit_test2('get_iso_country_code("+81367037781")   - src'         , get_iso_country_code_src("+81367037781")      , "JP")
    fail += unit_test2('get_iso_country_code("+8615021227397") - src'         , get_iso_country_code_src("+8615021227397")    , "CN")
    fail += unit_test2('get_iso_country_code("0000123456")     - src'         , get_iso_country_code_src("0000123456")       , "UNKNOWN")
    fail += unit_test2('get_iso_country_code("1111111111")     - src'         , get_iso_country_code_src("1111111111")        , "UNKNOWN")
    fail += unit_test2('get_iso_country_code("+8615021227397") - src'         , get_iso_country_code_src("+8615021227397")    , "CN")
    fail += unit_test2('get_iso_country_code("1222333")        - src'         , get_iso_country_code_src("1222333")           , "UNKNOWN")
    fail += unit_test2('get_iso_country_code("5555555")        - src'         , get_iso_country_code_src("5555555")          , "UNKNOWN")
    fail += unit_test2('get_iso_country_code("+19992539056")   - src'         , get_iso_country_code_src("+19992539056")      , "US")
    fail += unit_test2('get_iso_country_code("61730002247")    - src'         , get_iso_country_code_src("61730002247")       , "AU")
    fail += unit_test2('get_iso_country_code("00")             - src'         , get_iso_country_code_src("00")                , "UNKNOWN")
    fail += unit_test2('get_iso_country_code("0")              - src'         , get_iso_country_code_src("0")                 , "UNKNOWN")
    fail += unit_test2('get_iso_country_code("Restricted")     - src'         , get_iso_country_code_src("Restricted")        , "UNKNOWN")
    
  end
  
  def unit_test2(label, output, expected)
    if output.to_s != expected.to_s
      @tdd_output2 += ("<font color=\"red\">testing %s: expcted %s but we got %s.</font> <br />" % [label, expected.to_s, output.to_s])
      return 1
    else
      @tdd_output2 += ("testing %s succeed! We got %s. <br />" % [label, output])
      return 0
    end
  end
  
  def unit_test(label, output, expected)
    if output.to_s != expected.to_s
      @tdd_output += ("<font color=\"red\">testing %s: expcted %s but we got %s.</font> <br />" % [label, expected.to_s, output.to_s])
      return 1
    else
      @tdd_output += ("testing %s succeed! We got %s. <br />" % [label, output])
      return 0
    end
  end

end

################################################################
##
## This class is for making it easy to insert callcache_raw data
##
################################################################
class CallcacheRaw < ActiveRecord::Base
  
end